package store

import (
	"errors"
	"fmt"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"log"
	"sync"
	"time"
)

type (
	Sqlite struct {
		db *gorm.DB
	}
)

var (
	sqliteStore *Sqlite
	once        sync.Once
)

func GetSqlite() *Sqlite {

	if sqliteStore == nil {
		log.Fatal(errors.New("sqlite init fail"))
	}

	return sqliteStore
}

func InitSqlite() {
	once.Do(func() {
		sqliteStore = newSqlite()
	})
}

func newSqlite() *Sqlite {
	defer func() {
		if err := recover(); err != nil {
			log.Println("recover error:", err)
		}
	}()

	dbPath := "./go-send.db"
	db, err := gorm.Open(sqlite.Open(dbPath), &gorm.Config{})
	if err != nil {
		log.Fatal("failed to connect database")
	}
	sqlDB, _ := db.DB()
	sqlDB.SetMaxOpenConns(10)
	sqlDB.SetConnMaxLifetime(3000 * time.Second)

	if err := runMigrations(db); err != nil {
		log.Fatal(err)
	}

	log.Println("sqlite init success")
	return &Sqlite{db: db}
}

func (s *Sqlite) NewApiStore() *ApiStore {
	var api = &ApiStore{db: s.db}
	api.SaveOrUpdateDirectory(DirectoryEntity{Id: 1, DirectoryId: "1", DirectoryName: "Collection", ParentId: 0})
	return api
}

func (s *Sqlite) NewEnvStore() *EnvStore {
	return &EnvStore{db: s.db}
}

func runMigrations(gormDB *gorm.DB) error {

	err := gormDB.AutoMigrate(&InstanceEntity{}, &DirectoryEntity{}, &EnvironmentEntity{})
	if err != nil {
		return fmt.Errorf("failed to auto migrate: %v", err)
	}
	return nil
}
